<!--
 * @Description: 管理责任区域
 * @Author: wind-lc
 * @version: 1.0
 * @Date: 2021-09-16 14:34:28
 * @LastEditTime: 2023-05-11 10:53:55
 * @FilePath: \cscec-pms-admin\src\views\project\responsibilityAreaSetting\management.vue
-->
<template>
  <base-breadcrumb :title="$route.meta.title">
    <a-row :gutter="10">
      <!-- 树搜索 -->
      <a-col :span="6">
        <a-card>
          <title-name title="责任区域设置" />
          <div class="responsibility-area-setting-management">
            <a-input-search
              style="margin-bottom: 8px"
              placeholder="请搜索"
              @change="handleChange"
            />
            <div class="responsibility-area-setting-management-tree">
              <a-spin :spinning="loading">
                <a-tree
                  v-if="treeData.length > 0"
                  :expanded-keys="expandedKeys"
                  :auto-expand-parent="autoExpandParent"
                  :tree-data="treeData"
                  :replace-fields="replaceFields"
                  :selected-keys="selectedKeys"
                  @expand="handleExpand"
                  @select="handleSelect"
                >
                  <template
                    slot="title"
                    slot-scope="node"
                  >
                    <span v-if="node[replaceFields.title].indexOf(searchValue) > -1">
                      {{ node[replaceFields.title].substr(0, node[replaceFields.title].indexOf(searchValue)) }}<span
                        style="color: #f50">{{ searchValue }}</span>{{ node[replaceFields.title].substr(node[replaceFields.title].indexOf(searchValue) + searchValue.length) }}<span
                        v-if="node[replaceFields.status] === 0"
                        style="color: #f50"
                      >(停用)</span>
                    </span>
                    <span v-else>{{ node[replaceFields.title] }}
                      <span
                        v-if="node[replaceFields.status] === 0"
                        style="color: #f50"
                      >(停用)</span>
                    </span>
                  </template>
                </a-tree>
                <a-empty v-else />
              </a-spin>
            </div>
            <div class="responsibility-area-setting-management-btn">
              <a-button
                type="primary"
                :disabled="!(selectedKeys.length > 0)|| select[replaceFields.status]===0"
                @click="handleAreaAdd"
              >
                添加
              </a-button>
              <a-button
                type="primary"
                :disabled="disabledBtn"
                @click="handleAreaEdit"
              >
                编辑
              </a-button>
              <a-button
                type="danger"
                :disabled="disabledBtn"
                :loading="btnLoading"
                @click="handleAreaDelete"
              >
                删除
              </a-button>
              <a-button
                :type="switchText === '启用'?'primary':'danger'"
                :disabled="!(selectedKeys.length > 0)"
                :loading="btnLoading"
                @click="handleAreaSwitch"
              >
                {{ switchText }}
              </a-button>
            </div>
          </div>
        </a-card>
      </a-col>
      <a-col :span="18">
        <a-card>
          <title-name title="责任人设置" />
          <a-table
            :columns="columns"
            :data-source="data"
            bordered
            :pagination="false"
            :loading="tableLoading"
          >
            <template
              v-for="col in ['mainDutyPerson', 'fromDutyPerson', 'status']"
              :slot="col"
              slot-scope="text,record"
            >
              <div :key="col">
                <template v-if="record.edit">
                  <a-select
                    v-if="col === 'mainDutyPerson'"
                    v-model="record.mainDutyPersonValue"
                    placeholder="请选择"
                    show-search
                    option-filter-prop="children"
                    style="width: 100%"
                    :filter-option="filterOption"
                    mode="multiple"
                    option-label-prop="label"
                    label-in-value
                  >
                    <a-select-option
                      v-for="item in projectEmployees"
                      :key="item.userId"
                      :value="item.userId"
                      :label="item.name"
                    >
                      {{ item.name }}({{ item.phone }})
                    </a-select-option>
                  </a-select>
                  <a-select
                    v-if="col === 'fromDutyPerson'"
                    v-model="record.fromDutyPersonValue"
                    placeholder="请选择"
                    show-search
                    option-filter-prop="children"
                    style="width: 100%"
                    :filter-option="filterOption"
                    mode="multiple"
                    option-label-prop="label"
                    label-in-value
                  >
                    <a-select-option
                      v-for="item in projectEmployees"
                      :key="item.userId"
                      :value="item.userId"
                      :label="item.name"
                    >
                      {{ item.name }}({{ item.phone }})
                    </a-select-option>
                  </a-select>
                  <a-select
                    v-if="col === 'status'"
                    v-model="record.statusValue"
                    style="width: 100%"
                    placeholder="请选择"
                  >
                    <a-select-option :value="1">
                      启用
                    </a-select-option>
                    <a-select-option :value="0">
                      停用
                    </a-select-option>
                  </a-select>
                </template>
                <template v-else>
                  <template v-if="col === 'status'">
                    {{ text ===1?'启用':'停用' }}
                  </template>
                  <template v-else>
                    {{ text.map(el=>el.responsibility).join('，') }}
                  </template>
                </template>
              </div>
            </template>
            <template
              slot="operation"
              slot-scope="text,record"
            >
              <template v-if="record.edit">
                <a @click="handleSubmit(record)">提交</a>
                <a-divider type="vertical" />
                <a @click="handleCancel(record)">取消</a>
              </template>
              <a
                v-else
                @click="handleEdit(record)"
              >编辑</a>
            </template>
          </a-table>
        </a-card>
      </a-col>
      <!-- 树搜索 -->
    </a-row>
    <!-- 操作模态框 -->
    <AreaSettingOperation
      :visible.sync="visible"
      :data="nodeData"
      :type="AreaSettingType"
      @update="getData()"
    />
    <!-- 操作模态框 -->
  </base-breadcrumb>
</template>
<script>
import { Empty } from 'ant-design-vue'
import responsibilityAreaSetting from '@/api/project/responsibilityAreaSetting'
import AreaSettingOperation from './components/AreaSettingOperation'
import cloneDeep from 'lodash.clonedeep'
import { getNotConcurrentlyPeople } from '@/api/project/projects'
export default {
  name: 'ResponsibilityAreaSettingManagement',
  components: {
    AEmpty: Empty,
    AreaSettingOperation
  },
  data() {
    return {
      // 展开节点
      expandedKeys: [],
      // 搜索值
      searchValue: '',
      // 自动展开父节点
      autoExpandParent: true,
      // 树数据
      treeData: [],
      // 数据列表
      treeList: [],
      // 数据自动替换
      replaceFields: {
        children: 'children',
        title: 'dutyAreaName',
        key: 'id',
        status: 'status'
      },
      // 树加载
      loading: false,
      // 选中项
      selectedKeys: [],
      //表头
      columns: [
        {
          title: '序号',
          width: 80,
          align: 'center',
          customRender: (text, record, index) => {
            return index + 1
          }
        },
        {
          title: '主责任人',
          width: '50%',
          dataIndex: 'mainDutyPerson',
          scopedSlots: { customRender: 'mainDutyPerson' }
        },
        {
          title: '从责任人',
          width: '50%',
          dataIndex: 'fromDutyPerson',
          scopedSlots: { customRender: 'fromDutyPerson' }
        },
        {
          title: '状态',
          width: 200,
          dataIndex: 'status',
          scopedSlots: { customRender: 'status' }
        },
        {
          title: '操作',
          dataIndex: 'operation',
          width: 160,
          align: 'center',
          scopedSlots: { customRender: 'operation' }
        }
      ],
      //树选中项
      select: {},
      //表格数据
      data: [],
      // 操作模态框显示隐藏
      visible: false,
      // 操作数据
      nodeData: {},
      // 操作数据类型
      AreaSettingType: '',
      // 按钮加载
      btnLoading: false,
      // 项目人员
      projectEmployees: [],
      // 项目人员表格加载
      tableLoading: false
    }
  },
  computed: {
    // 按钮禁用
    disabledBtn() {
      return !(this.selectedKeys.length > 0 && this.selectedKeys[0] !== this.treeData[0][this.replaceFields.key])
    },
    // 停用启用文字
    switchText() {
      return this.select.status === 1 ? '停用' : '启用'
    }
  },
  mounted() {
    this.getData()
    this.getProjectEmployees()
  },
  methods: {
    /**
     * @description: 扁平化数据
     * @param {array} data
     * @return {void}
     */
    flatTree(tree) {
      for (let i = 0; i < tree.length; i++) {
        const node = tree[i]
        const key = node[this.replaceFields.key]
        const title = node[this.replaceFields.title]
        node.scopedSlots = { title: 'title' }
        this.treeList.push({ [this.replaceFields.key]: key, [this.replaceFields.title]: title })
        if (node[this.replaceFields.children]) {
          this.flatTree(node[this.replaceFields.children])
        }
      }
    },
    /**
     * @description: 搜索父节点
     * @param {string} key
     * @param {array} tree
     * @return {void}
     */
    getParentKey(key, tree) {
      let parentKey
      for (let i = 0; i < tree.length; i++) {
        const node = tree[i]
        if (node[this.replaceFields.children]) {
          if (node[this.replaceFields.children].some((item) => item[this.replaceFields.key] === key)) {
            parentKey = node[this.replaceFields.key]
          } else if (this.getParentKey(key, node[this.replaceFields.children])) {
            parentKey = this.getParentKey(key, node[this.replaceFields.children])
          }
        }
      }
      return parentKey
    },
    /**
     * @description: 搜索改变
     * @param {void}
     * @return {void}
     */
    handleChange(e) {
      const value = e.target.value
      const expandedKeys = this.treeList
        .map((item) => {
          if (item[this.replaceFields.title].indexOf(value) > -1) {
            return this.getParentKey(item[this.replaceFields.key], this.treeData)
          }
          return null
        })
        .filter((item, i, self) => item && self.indexOf(item) === i)
      Object.assign(this, {
        expandedKeys,
        searchValue: value,
        autoExpandParent: true
      })
    },
    /**
     * @description: 节点展开收缩
     * @param {string} expandedKeys
     * @return {void}
     */
    handleExpand(expandedKeys) {
      this.expandedKeys = expandedKeys
      this.autoExpandParent = false
    },
    /**
     * @description: 树选择
     * @param {array} selectedKeys 选中key
     * @param {array} selectedNodes 选中节点
     * @return {void}
     */
    handleSelect(selectedKeys, { selectedNodes }) {
      this.selectedKeys = selectedKeys
      const list = selectedNodes[0]?.data.props.dataRef[this.replaceFields.children] || []
      const node = selectedNodes[0]?.data.props.dataRef || {}
      this.select = node
      if (node?.dutyAreaName && node?.dutyAreaName !== '所有') {
        // 不是第一层级(所有)
        if (list && list.length === 0) {
          // 树最后一级节点
          this.setResponsible()
        } else {
          this.data = []
        }
      } else {
        this.data = []
      }
    },
    /**
     * @description: 获取数据
     * @param {array} key 选中项
     * @return {void}
     */
    getData(key = []) {
      this.loading = true
      this.tableLoading = true
      responsibilityAreaSetting
        .dutyAreaSettingDetail(this.$route.query.id)
        .then(({ code, data }) => {
          if (code === 200) {
            this.treeData = [data]
            this.flatTree(this.treeData)
            if (key.length === 0) {
              // 默认选中第一个
              this.selectedKeys = [this.treeData[0][this.replaceFields.key]]
              this.select = this.treeData[0]
              const node = selectedNodes[0]?.data.props.dataRef || {}
              if (node?.dutyAreaName && node?.dutyAreaName !== '所有') {
                // 不是第一层级(所有)
                this.setResponsible()
              } else {
                this.data = []
              }
            } else {
              // 选中指定节点
              this.selectedKeys = [...key]
              this.select = this.getSelect(this.treeData, this.selectedKeys[0])
              this.setResponsible()
            }
          } else {
            this.treeData = []
          }
        })
        .finally(() => {
          this.loading = false
          this.tableLoading = false
        })
    },
    /**
     * @description: 设置责任人
     * @param {void}
     * @return {void}
     */
    setResponsible() {
      if (this.select.dutyPersonSettingVO === null) {
        this.data = [
          {
            mainDutyPerson: [],
            mainDutyPersonValue: [],
            fromDutyPerson: [],
            fromDutyPersonValue: [],
            status: 1,
            statusValue: 1
          }
        ]
      } else {
        const obj = cloneDeep(this.select.dutyPersonSettingVO)
        obj.mainDutyPersonValue = obj.mainDutyPerson.map((el) => {
          return {
            key: el.responsibilityId,
            label: el.responsibility
          }
        })
        obj.fromDutyPersonValue = obj.fromDutyPerson.map((el) => {
          return {
            key: el.responsibilityId,
            label: el.responsibility
          }
        })
        obj.statusValue = obj.status
        this.data = [obj]
      }
    },
    /**
     * @description: 遍历树获取节点
     * @param {array} tree 树
     * @param {string} key 节点key
     * @return {object} 节点
     */
    getSelect(tree, key) {
      for (let i = 0; i < tree.length; i++) {
        if (tree[i][this.replaceFields.key] === key) {
          return tree[i]
        }
        if (tree[i][this.replaceFields.children]) {
          let node = this.getSelect(tree[i][this.replaceFields.children], key)
          if (node) return node
        }
      }
    },
    /**
     * @description: 获取项目下人员
     * @param {void}
     * @return {void}
     */
    getProjectEmployees() {
      responsibilityAreaSetting
        .queryProjectEmployees({ projectId: this.$route.query.projectId })
        .then(({ code, data }) => {
          if (code === 200) {
            this.projectEmployees = data
          } else {
            this.projectEmployees = []
          }
        })
        .catch((error) => {
          this.projectEmployees = []
        })
    },
    /**
     * @description: 编辑责任人
     * @param {object} record 行数据
     * @return {void}
     */
    handleEdit(record) {
      record.edit = true
      record.mainDutyPersonValue = record.mainDutyPerson.map((el) => {
        return {
          key: el.responsibilityId,
          label: el.responsibility
        }
      })
      record.fromDutyPersonValue = record.fromDutyPerson.map((el) => {
        return {
          key: el.responsibilityId,
          label: el.responsibility
        }
      })
      record.statusValue = record.status
      this.data = [record]
    },
    /**
     * @description: 提交责任人
     * @param {object} record 行数据
     * @return {void}
     */
    handleSubmit(record) {
      const { id } = record
      let params = (params = {
        dutyAreaSettingId: this.select.id,
        fromDutyPerson: record.fromDutyPersonValue.map((el) => {
          return {
            responsibility: el.label,
            responsibilityId: el.key
          }
        }),
        mainDutyPerson: record.mainDutyPersonValue.map((el) => {
          return {
            responsibility: el.label,
            responsibilityId: el.key
          }
        }),
        status: record.statusValue
      })
      let fn = null
      if (id) {
        // 编辑
        params.id = id
        fn = responsibilityAreaSetting.updateDutyPersonSetting
      } else {
        // 新增
        fn = responsibilityAreaSetting.addDutyPersonSetting
      }
      fn(params).then(({ code }) => {
        if (code === 200) {
          this.$message.success('操作成功')
          record.edit = false
          this.data = [record]
          //  刷新责任区域树
          this.getData(this.selectedKeys)
        }
      })
    },
    /**
     * @description: 取消
     * @param {object} record 行数据
     * @return {void}
     */
    handleCancel(record) {
      record.edit = false
      this.data = [record]
    },
    /**
     * @description: 新增区域设置
     * @param {void}
     * @return {void}
     */
    handleAreaAdd() {
      this.nodeData = this.select
      if (this.nodeData.dutyPersonSettingVO === null) {
        this.visible = true
        this.AreaSettingType = 'add'
      } else {
        const vm = this
        this.$confirm({
          title: '提示',
          content: '只有最末级的区域可设置责任人，若要添加该区域的下级区域，系统将自动删除该区域已设置的责任人信息',
          okType: 'danger',
          onOk() {
            responsibilityAreaSetting
              .deleteDutyPersonSetting({ dutyAreaSettingId: vm.nodeData.id, id: vm.nodeData.dutyPersonSettingVO.id })
              .then(({ code }) => {
                if (code === 200) {
                  vm.visible = true
                  vm.AreaSettingType = 'add'
                }
              })
          }
        })
      }
    },
    /**
     * @description: 编辑区域设置
     * @param {void}
     * @return {void}
     */
    handleAreaEdit() {
      this.visible = true
      this.nodeData = this.select
      this.AreaSettingType = 'edit'
    },
    /**
     * @description: 删除区域设置
     * @param {void}
     * @return {void}
     */
    handleAreaDelete() {
      this.nodeData = this.select
      const { id } = this.nodeData
      const vm = this
      this.btnLoading = true
      this.$confirm({
        title: '提示',
        content: '请确认是否要删除，删除父级区域，其下属子级区域将被全部删除',
        okType: 'danger',
        onOk() {
          responsibilityAreaSetting
            .deleteDutyAreaSetting({ id })
            .then(({ code }) => {
              if (code === 200) {
                vm.$message.success('操作成功')
                vm.getData()
              }
            })
            .finally(() => {
              vm.btnLoading = false
            })
        },
        onCancel() {
          vm.btnLoading = false
        }
      })
    },
    /**
     * @description: 启用停用区域设置
     * @param {void}
     * @return {void}
     */
    handleAreaSwitch() {
      this.nodeData = this.select
      const { dutyAreaName, id, parentId, status } = this.nodeData
      this.btnLoading = true
      if (status === 1) {
        const vm = this
        this.$confirm({
          title: '提示',
          content: '请确认是否要停用，停用父级区域，其下属子级区域将同步停用',
          okType: 'danger',
          onOk() {
            vm.switchFun({ dutyAreaName, id, parentId, status: 0 })
          },
          onCancel() {
            vm.btnLoading = false
          }
        })
      } else {
        this.switchFun({ dutyAreaName, id, parentId, status: 1 })
      }
    },
    /**
     * @description: 启用停用接口
     * @param {object} params 接口参数
     * @return {void}
     */
    switchFun(params) {
      responsibilityAreaSetting
        .updateDutyAreaSetting(params)
        .then(({ code }) => {
          if (code === 200) {
            this.$message.success('操作成功')
            this.getData()
          }
        })
        .finally(() => {
          this.btnLoading = false
        })
    },
    /**
     * @description: 过滤项目下人员
     * @param {string} input 搜索值
     * @param {obnject} option 节点
     * @return {boolean} 是否符合过滤条件
     */
    filterOption(input, option) {
      return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
    }
  }
}
</script>
<style lang="less" scoped>
.responsibility-area-setting-management {
  min-height: calc(var(--heightVh) - 300px);
  display: flex;
  flex-flow: column;
}
.responsibility-area-setting-management-tree {
  overflow: auto;
  flex: 1;
  &::-webkit-scrollbar {
    background: #fff;
    width: 8px;
    height: 8px;
    // display: none;
  }
  &::-webkit-scrollbar-thumb {
    /*滚动条里面小方块*/
    width: 8px;
    border-radius: 8px;
    border: 1px #fff solid;
    background: #ccc;
  }
}
.responsibility-area-setting-management-btn {
  margin-top: 8px;
  display: flex;
  justify-content: space-evenly;
  flex-wrap: wrap;
  .ant-btn {
    margin: 5px 0;
  }
}
</style>
